package edu.study.common.validation;

import edu.study.api.common.dto.BaseDto;
import edu.study.api.common.dto.BaseReqDto;
import edu.study.api.common.dto.RespDto;
import edu.study.api.common.enums.BaseResultCodeEnum;
import edu.study.common.exception.BizException;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;

@Slf4j
public class RequestValidator {

	public static void validate(BaseReqDto req) {
		ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
		Validator validator = vf.getValidator();
		Set<ConstraintViolation<BaseReqDto>> voilationSet = validator.validate(req);
		if (!voilationSet.isEmpty()) {
			StringBuilder message = new StringBuilder();
			for (ConstraintViolation<BaseReqDto> voilation : voilationSet) {
				message.append(voilation.getPropertyPath() + ":" + voilation.getMessage() + "; ");
			}
			throw new BizException(BaseResultCodeEnum.INVALID_REQUEST_PARAM, message.toString());
		}
	}

	public static void validate(BaseDto req) {
		ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
		Validator validator = vf.getValidator();
		Set<ConstraintViolation<BaseDto>> voilationSet = validator.validate(req);
		if (!voilationSet.isEmpty()) {
			StringBuilder message = new StringBuilder();
			for (ConstraintViolation<BaseDto> voilation : voilationSet) {
				message.append(voilation.getPropertyPath() + ":" + voilation.getMessage() + "; ");
			}
			throw new BizException(BaseResultCodeEnum.INVALID_REQUEST_PARAM, message.toString());
		}
	}

	@SuppressWarnings("rawtypes")
	public static void validateWithGroups(BaseDto req, Class... groups) {
		ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
		Validator validator = vf.getValidator();
		Set<ConstraintViolation<BaseDto>> voilationSet = validator.validate(req, groups);
		if (!voilationSet.isEmpty()) {
			StringBuilder message = new StringBuilder();
			for (ConstraintViolation<BaseDto> voilation : voilationSet) {
				message.append(voilation.getPropertyPath() + ":" + voilation.getMessage() + "; ");
			}
			throw new BizException(BaseResultCodeEnum.INVALID_REQUEST_PARAM, message.toString());
		}
	}

	@SuppressWarnings("rawtypes")
	public static RespDto validateResp(BaseReqDto req) {
		RespDto resp = new RespDto();
		ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
		Validator validator = vf.getValidator();
		Set<ConstraintViolation<BaseReqDto>> voilationSet = validator.validate(req);
		if (!voilationSet.isEmpty()) {
			StringBuilder message = new StringBuilder();
			for (ConstraintViolation<BaseReqDto> voilation : voilationSet) {
				message.append(voilation.getPropertyPath() + ":" + voilation.getMessage() + "; ");
			}
			log.error("validateResp end, message={}", message.toString());
			resp.setResultFail(message.toString());
		}
		return resp;
	}

	@SuppressWarnings("rawtypes")
	public static RespDto validateResp(BaseDto req) {
		RespDto resp = new RespDto();
		ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
		Validator validator = vf.getValidator();

		Set<ConstraintViolation<BaseDto>> voilationSet = validator.validate(req);

		if (!voilationSet.isEmpty()) {
			StringBuilder message = new StringBuilder();
			for (ConstraintViolation<BaseDto> voilation : voilationSet) {
				message.append(voilation.getPropertyPath() + ":" + voilation.getMessage() + "; ");
			}
			log.error("validateResp end, message={}", message.toString());
			resp.setResultFail(message.toString());
		}
		return resp;
	}

	@SuppressWarnings("rawtypes")
	public static RespDto validateWithGroupResp(BaseDto req, Class... groups) {
		RespDto resp = new RespDto();
		ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
		Validator validator = vf.getValidator();
		Set<ConstraintViolation<BaseDto>> voilationSet = validator.validate(req, groups);
		if (!voilationSet.isEmpty()) {
			StringBuilder message = new StringBuilder();
			for (ConstraintViolation<BaseDto> voilation : voilationSet) {
				message.append(voilation.getPropertyPath() + ":" + voilation.getMessage() + "; ");
			}
			log.error("validateWithGroup end, message={}", message.toString());
			resp.setResultFail(message.toString());
		}
		return resp;
	}
}
